/**
 * Created by yazhou on 17/6/28.
 */

'use strict'

import { constants } from './constants'
import { Session } from './session'
import { extend } from './extend'
import { sign } from './sign'

/***
 * @class
 * 表示登录过程中发生的异常
 */
let LoginError = (function () {
  function LoginError(type, message) {
    Error.call(this, message)
    this.type = type
    this.message = message
  }

  LoginError.prototype = new Error()
  LoginError.prototype.constructor = LoginError

  return LoginError
})()

/**
 * 微信登录，获取 code 和 encryptData
 */
let getWxLoginResult = function getLoginCode(callback) {
  wx.login({
    success: function (loginResult) {
      wx.getUserInfo({
        success: function (userResult) {
          callback(null, {
            code: loginResult.code,
            encryptedData: userResult.encryptedData,
            rawData: userResult.rawData,
            signature: userResult.signature,
            iv: userResult.iv,
            userInfo: userResult.userInfo
          })
        },

        fail: function (userError) {
          // getUserInfo:fail auth deny   获取用户信息失败，
          // var error = new LoginError(constants.ERR_WX_GET_USER_INFO, '请重新进行微信授权')      
          // let VisitFlagCount = wx.getStorageSync('VisitFlagCount')

          // if (!VisitFlagCount) {
          //   wx.showModal({
          //     title: '用户未授权',
          //     content: '授权失败，无法使用支付等高级功能',
          //     showCancel: false
          //   })
          // } 
          // else {
            // wx.showModal({
            //   title: '用户未授权',
            //   content: '如需正常使用高级功能，请按确定并在授权管理中选中“用户信息”，然后点按确定。最后再重新进入小程序即可正常使用。',
            //   showCancel: false,
            //   success: function (res) {
            //     if (res.confirm) {
            //       wx.openSetting({
            //         success: function success(res) {
                      
            //         }
            //       })
            //     }
            //   }
            // })
          // }

          // wx.setStorageSync('VisitFlagCount', 1)
        }
      })
    },

    fail: function (loginError) {
      var error = new LoginError(constants.ERR_WX_LOGIN_FAILED, '微信登录失败，请检查网络状态')
      error.detail = loginError
      callback(error, null)
    }
  })
}

let noop = function noop() { }
let defaultOptions = {
  method: 'GET',
  success: noop,
  fail: noop,
  loginUrl: null
}

/**
 * @method
 * 进行服务器登录，以获得登录会话
 *
 * @param {Object} options 登录配置
 * @param {string} options.loginUrl 登录使用的 URL，服务器应该在这个 URL 上处理登录请求
 * @param {string} [options.method] 请求使用的 HTTP 方法，默认为 "GET"
 * @param {Function} options.success(userInfo) 登录成功后的回调函数，参数 userInfo 微信用户信息
 * @param {Function} options.fail(error) 登录失败后的回调函数，参数 error 错误信息
 */
let login = function login(options) {
  options = extend({}, defaultOptions, options)

  if (! defaultOptions.loginUrl) {
    options.fail(new LoginError(constants.ERR_INVALID_PARAMS, '登录错误：缺少登录地址，请通过 setLoginUrl() 方法设置登录地址'))

    return
  }

  var doLogin = () => getWxLoginResult(function (wxLoginError, wxLoginResult) {
    if (wxLoginError) {
      options.fail(wxLoginError)

      return
    } 

    var userInfo = wxLoginResult.userInfo

    // 构造请求头，包含 code、encryptedData 和 iv
    var code = wxLoginResult.code
    var encryptedData = wxLoginResult.encryptedData
    var rawData = wxLoginResult.rawData
    var signature = wxLoginResult.signature
    var iv = wxLoginResult.iv
    var header = {}

    header[constants.WX_HEADER_NO_CHECK] = 1
    header[constants.WX_HEADER_CODE] = code
    header[constants.WX_HEADER_ENCRYPTED_DATA] = encryptedData
    header[constants.WX_HEADER_RAW_DATA] = encodeURIComponent(rawData)
    header[constants.WX_HEADER_SIGNATURE] = signature
    header[constants.WX_HEADER_IV] = iv
    
    let requestOptions = {
	    url: options.loginUrl,
	    header: header,
	    method: options.method,
	    data: options.data || {},
	    success: function (result) {
		    var data = result.data.original.data
		
		    // 成功地响应会话信息
		    if (data && data[constants.WX_SESSION_MAGIC_ID]) {
			    // 小程序授权登录成功
			    // 已绑定小程序的用户，记录mobile_phone、openid
			    userInfo = extend(true, {}, userInfo, data)

          if (options.authorizeLogin && data.uid) {
            wx.navigateBack()
          }

			    try {
				    wx.setStorageSync('userinfo', userInfo)
			    } catch (e) {
				    //
			    }
			
			    Session.set(data)
			    options.success(userInfo)
		    } else { // 没有正确响应会话信息
			    var errorMessage = '登录请求没有包含会话响应，' + result.data.original.msg
			    var noSessionError = new LoginError(constants.ERR_LOGIN_SESSION_NOT_RECEIVED, errorMessage)
			
			    options.fail(noSessionError)
		    }
	    },
	
	    // 响应错误
	    fail: function (loginResponseError) {
		    var error = new LoginError(constants.ERR_LOGIN_FAILED, '登录失败，网络错误')
		
		    options.fail(error)
	    }
    }
    
    sign(requestOptions)
    
    // 请求服务器登录地址，获得会话信息
    wx.request(requestOptions)
  })

  var session = Session.get()

  if (session && session.openid) {
    wx.checkSession({
      success: function () {
        options.success(session)
      },

      fail: function () {
        Session.clear()
        doLogin()
      }
    })
  } else {
    doLogin()
  }
}

let setLoginUrl = function (loginUrl) {
  defaultOptions.loginUrl = loginUrl
}

export { LoginError, login, setLoginUrl }
